home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun4c.md / unpack.c < prev    next >
C/C++ Source or Header  |  1989-08-17  |  5KB  |  221 lines

  1. #ifdef sccsid
  2. static char     sccsid[] = "@(#)unpack.c 1.5 88/02/08 Copyr 1987 Sun Micro";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1987 by Sun Microsystems, Inc. 
  7.  */
  8.  
  9. /* Unpack procedures for Sparc FPU simulator. */
  10.  
  11. /*
  12.  * This whole file refuses to lint.
  13.  */
  14. #ifndef lint
  15. #include <sun4/fpu/fpu_simulator.h>
  16. #include <sun4/fpu/globals.h>
  17.  
  18. PRIVATE void
  19. leftshift(pu, n)
  20.     unpacked       *pu;
  21.     unsigned        n;
  22.  
  23. /* Left shift significand by n bits.  Affect all classes.     */
  24.  
  25. {
  26.     while (n >= 32) {    /* big shift */
  27.         (*pu).significand[0] = (*pu).significand[1];
  28.         (*pu).significand[1] = (*pu).significand[2];
  29.         (*pu).significand[2] = 0;
  30.         n -= 32;
  31.     }
  32.     while (n > 0) {        /* small shift */
  33.         pu->significand[0] = pu->significand[0] << 1;
  34.         if (pu->significand[1] & 0x80000000)
  35.             pu->significand[0] |= 1;
  36.         pu->significand[1] = pu->significand[1] << 1;
  37.         if (pu->significand[2] & 0x80000000)
  38.             pu->significand[1] |= 1;
  39.         pu->significand[2] = pu->significand[2] << 1;
  40.         n -= 1;
  41.     }
  42. }
  43.  
  44. PRIVATE void
  45. unpackinteger(pu, x)
  46.     unpacked       *pu;    /* unpacked result */
  47.     int             x;    /* packed integer */
  48. {
  49.     if (x == 0) {
  50.         pu->sign = 0;
  51.         pu->fpclass = fp_zero;
  52.     } else {
  53.         (*pu).sign = x < 0;
  54.         (*pu).fpclass = fp_normal;
  55.         (*pu).exponent = INTEGER_BIAS;
  56.         (*pu).significand[0] = (x >= 0) ? x : -x;
  57.         (*pu).significand[1] = 0;
  58.         (*pu).significand[2] = 0;
  59.         fpu_normalize(pu);
  60.     }
  61. }
  62.  
  63. void
  64. unpacksingle(pu, x)
  65.     unpacked       *pu;    /* unpacked result */
  66.     single_type     x;    /* packed single */
  67. {
  68.     (*pu).sign = x.sign;
  69.     pu->significand[1] = 0;
  70.     pu->significand[2] = 0;
  71.     if (x.exponent == 0) {    /* zero or sub */
  72.         if (x.significand == 0) {    /* zero */
  73.             pu->fpclass = fp_zero;
  74.             return;
  75.         } else {    /* subnormal */
  76.             pu->fpclass = fp_normal;
  77.             pu->exponent = -SINGLE_BIAS;
  78.             pu->significand[0] = x.significand << 9;
  79.             fpu_normalize(pu);
  80.             return;
  81.         }
  82.     } else if (x.exponent == 0xff) {    /* inf or nan */
  83.         if (x.significand == 0) {    /* inf */
  84.             pu->fpclass = fp_infinity;
  85.             return;
  86.         } else {    /* nan */
  87.             if ((x.significand & 0x400000) != 0) {    /* quiet */
  88.                 pu->fpclass = fp_quiet;
  89.             } else {/* signaling */
  90.                 pu->fpclass = fp_signaling;
  91.                 fpu_set_exception(fp_invalid);
  92.             }
  93.             pu->significand[0] = 0x40000000 | (x.significand << 8);
  94.             return;
  95.         }
  96.     }
  97.     (*pu).exponent = x.exponent - SINGLE_BIAS;
  98.     (*pu).fpclass = fp_normal;
  99.     (*pu).significand[0] = 0x80000000 | (x.significand << 8);
  100. }
  101.  
  102. void
  103. unpackdouble(pu, x, y)
  104.     unpacked       *pu;    /* unpacked result */
  105.     double_type     x;    /* packed double */
  106.     unsigned        y;
  107. {
  108.     (*pu).sign = x.sign;
  109.     pu->significand[1] = y;
  110.     pu->significand[2] = 0;
  111.     if (x.exponent == 0) {    /* zero or sub */
  112.         if ((x.significand == 0) && (y == 0)) {    /* zero */
  113.             pu->fpclass = fp_zero;
  114.             return;
  115.         } else {    /* subnormal */
  116.             pu->fpclass = fp_normal;
  117.             pu->exponent = 12 - DOUBLE_BIAS;
  118.             pu->significand[0] = x.significand;
  119.             fpu_normalize(pu);
  120.             return;
  121.         }
  122.     } else if (x.exponent == 0x7ff) {    /* inf or nan */
  123.         if ((x.significand == 0) && (y == 0)) {    /* inf */
  124.             pu->fpclass = fp_infinity;
  125.             return;
  126.         } else {    /* nan */
  127.             if ((x.significand & 0x80000) != 0) {    /* quiet */
  128.                 pu->fpclass = fp_quiet;
  129.             } else {/* signaling */
  130.                 pu->fpclass = fp_signaling;
  131.                 fpu_set_exception(fp_invalid);
  132.             }
  133.             pu->significand[0] = 0x80000 | x.significand;
  134.             leftshift(pu, 11);
  135.             return;
  136.         }
  137.     }
  138.     (*pu).exponent = x.exponent - DOUBLE_BIAS;
  139.     (*pu).fpclass = fp_normal;
  140.     (*pu).significand[0] = 0x100000 | x.significand;
  141.     leftshift(pu, 11);
  142. }
  143.  
  144. PRIVATE void
  145. unpackextended(pu, x, y, z)
  146.     unpacked       *pu;    /* unpacked result */
  147.     extended_type   x;    /* packed extended */
  148.     unsigned        y, z;
  149. {
  150.     (*pu).sign = x.sign;
  151.     (*pu).fpclass = fp_normal;
  152.     (*pu).exponent = x.exponent - EXTENDED_BIAS;
  153.     (*pu).significand[0] = y;
  154.     (*pu).significand[1] = z;
  155.     (*pu).significand[2] = 0;
  156.     if (x.exponent < 0x7fff) {    /* zero, normal, or subnormal */
  157.         if ((z == 0) && (y == 0)) {    /* zero */
  158.             pu->fpclass = fp_zero;
  159.             return;
  160.         } else {    /* normal or subnormal */
  161.             fpu_normalize(pu);
  162.             return;
  163.         }
  164.     } else {    /* inf or nan */
  165.         if ((z == 0) && (y == 0)) {    /* inf */
  166.             pu->fpclass = fp_infinity;
  167.             return;
  168.         } else {    /* nan */
  169.             if ((y & 0x40000000) != 0) {    /* quiet */
  170.                 pu->fpclass = fp_quiet;
  171.             } else {/* signaling */
  172.                 pu->fpclass = fp_signaling;
  173.                 fpu_set_exception(fp_invalid);
  174.             }
  175.             pu->significand[0] |= 0x40000000; /* make quiet */
  176.             return;
  177.         }
  178. }
  179. }
  180.  
  181. void
  182. _fp_unpack(pu, n, dtype)
  183.     unpacked       *pu;    /* unpacked result */
  184.     unsigned        n;    /* register where data starts */
  185.     enum fp_op_type dtype;    /* type of datum */
  186.  
  187. {
  188.     freg_type       f, fy, fz;
  189.  
  190.     switch ((int) dtype) {
  191.     case fp_op_integer:
  192.         _fp_current_read_freg(&f, n);
  193.         unpackinteger(pu, f.int_reg);
  194.         break;
  195.     case fp_op_single:
  196.         _fp_current_read_freg(&f, n);
  197.         unpacksingle(pu, f.single_reg);
  198.         break;
  199.     case fp_op_double:
  200.         _fp_current_read_freg(&f, DOUBLE_E(n));
  201.         _fp_current_read_freg(&fy, DOUBLE_F(n));
  202.         unpackdouble(pu, f.double_reg, fy.unsigned_reg);
  203.         break;
  204.     case fp_op_extended:
  205.         _fp_current_read_freg(&f, EXTENDED_E(n));
  206.         _fp_current_read_freg(&fy, EXTENDED_F(n));
  207.         _fp_current_read_freg(&fz, EXTENDED_FLOW(n));
  208.         unpackextended(pu, f.extended_reg, fy.unsigned_reg, fz.unsigned_reg);
  209.         break;
  210.     }
  211. }
  212.  
  213. void
  214. _fp_unpack_word(pu, n)
  215.     unsigned       *pu;    /* unpacked result */
  216.     unsigned        n;    /* register where data starts */
  217. {
  218.     _fp_current_read_freg(pu, n);
  219. }
  220. #endif /* lint */
  221.